﻿

#include "CPlcItemEditWidget.h"
#include "ui_CPlcItemEditWidget.h"

CPlcItemEditWidget::CPlcItemEditWidget(QWidget *parent)
    : QWidget(parent), ui(new Ui::CPlcItemEditWidget)
{
    ui->setupUi(this);
    mComboboxType = CPlcItemEditWidget::Contact;
    mComboboxName = CPlcItemEditWidget::Input;
    reloadLanguage();

    connect(ui->cb_Type, SIGNAL(currentIndexChanged(int)), this,
            SLOT(slotChangeComboboxType(int)));
    connect(ui->cb_Name, SIGNAL(currentIndexChanged(QString)), this,
            SLOT(slotChangeComboboxName(QString)));
    connect(ui->cb_ParameterType, SIGNAL(currentIndexChanged(int)), this,
            SLOT(slotChangeComboboxParameterType(int)));
}

CPlcItemEditWidget::~CPlcItemEditWidget()
{
    delete ui;
}

//更新数据到界面
void CPlcItemEditWidget::setDataToUi(SItemData &itemData)
{
    mLastItemData = itemData;
    blockSignals(true);
    setComboboxType(itemData.component.type);
    setComboboxName(itemData.component.name);
    ui->sb_Num->setValue(itemData.component.code);
    ui->sb_Parameter->setValue(itemData.component.param);
    blockSignals(false);
}

//从界面获取数据
SItemData CPlcItemEditWidget::getDataFromUi()
{
    int32_t type_                    = ui->cb_Type->currentIndex();
    int32_t name_                    = ui->cb_Name->currentIndex();
    uint16_t module                  = ui->sb_Num->value();
    int32_t bit                      = ui->sb_Bit->value();
    QString nameStr                  = ui->cb_Name->currentText();
    mLastItemData.component.code     = module;
    mLastItemData.component.param    = ui->sb_Parameter->value();
    mLastItemData.component.parmType = ui->cb_ParameterType->currentIndex();
    if (nameStr == "UI")
    {
        nameStr.append(QString::number(module))
            .append(".")
            .append(QString::number(bit));
        mLastItemData.component.param = bit;
    }
    else
    {
        nameStr.append(QString::number(module));
    }
    mLastItemData.variableNum = nameStr;

    switch (mComboboxType)
    {
    case CPlcItemEditWidget::Contact:
        mLastItemData.component.type = mContactTypeMap.value(type_);
        break;
    case CPlcItemEditWidget::Coil:
        mLastItemData.component.type = mCoilTypeMap.value(type_);
        break;
    case CPlcItemEditWidget::TON:
        mLastItemData.component.type = plc::TON;
        if (name_ == 0)
            mLastItemData.component.name = plc::Timer_T;
        else
            mLastItemData.component.name = plc::Timer_ST;
        break;
    case CPlcItemEditWidget::TOF:
        mLastItemData.component.type = plc::TOF;
        if (name_ == 0)
            mLastItemData.component.name = plc::Timer_T;
        else
            mLastItemData.component.name = plc::Timer_ST;
        break;
    case CPlcItemEditWidget::TONR:
        mLastItemData.component.type = plc::TONR;
        if (name_ == 0)
            mLastItemData.component.name = plc::Timer_T;
        else
            mLastItemData.component.name = plc::Timer_ST;
        break;
    case CPlcItemEditWidget::CTU:
        mLastItemData.component.type = plc::CTU;
        mLastItemData.component.name = plc::Counter_CTU;
        break;
    case CPlcItemEditWidget::RST:
        mLastItemData.component.type = plc::RST;
        if (name_ == 0)
            mLastItemData.component.name = plc::Counter_CTU;
        else if (name_ == 1)
            mLastItemData.component.name = plc::Timer_T;
        else
            mLastItemData.component.name = plc::Timer_ST;
        break;
    default:
        break;
    }

    switch (mComboboxName)
    {
    case CPlcItemEditWidget::Input:
        mLastItemData.component.name = mInputNameMap.value(name_);
        break;
    case CPlcItemEditWidget::Ouput:
        mLastItemData.component.name = mOuputNameMap.value(name_);
        break;
    default:
        break;
    }
    return mLastItemData;
}

//重新设置界面显示语言
void CPlcItemEditWidget::reloadLanguage()
{
    //////////类型
    //触点
    mContactTypeList.clear();
    mContactTypeList << QString::fromLocal8Bit("常开触点")
                     << QString::fromLocal8Bit("常闭触点")
                     << QString::fromLocal8Bit("上升沿")
                     << QString::fromLocal8Bit("下降沿");
    mContactTypeMap.clear();
    mContactTypeMap.insert(0, plc::OpenContact);
    mContactTypeMap.insert(1, plc::CloseContact);
    mContactTypeMap.insert(2, plc::Pulse);
    mContactTypeMap.insert(3, plc::Falling);

    //线圈
    mCoilTypeList.clear();
    mCoilTypeList << QString::fromLocal8Bit("线圈")
                  << QString::fromLocal8Bit("置位")
                  << QString::fromLocal8Bit("复位");
    mCoilTypeMap.clear();
    mCoilTypeMap.insert(0, plc::Coil);
    mCoilTypeMap.insert(1, plc::Set);
    mCoilTypeMap.insert(2, plc::Reset);

    //功能块
    mFunctionTypeList.clear();
    mFunctionTypeList << QString::fromLocal8Bit("TON")
                      << QString::fromLocal8Bit("TOF")
                      << QString::fromLocal8Bit("TONR")
                      << QString::fromLocal8Bit("CTU")
                      << QString::fromLocal8Bit("RST");
    mFunctionTypeMap.clear();
    mFunctionTypeMap.insert(0, plc::TON);
    mFunctionTypeMap.insert(1, plc::TOF);
    mFunctionTypeMap.insert(2, plc::TONR);
    mFunctionTypeMap.insert(3, plc::CTU);
    mFunctionTypeMap.insert(4, plc::RST);
    //////////名称
    //输入
    mInputNameList.clear();
    mInputNameList << "X"
                   << "SX"
                   << "Y"
                   << "SY"
                   << "SMC"
                   << "MC"
                   << "UI"
                   << "C"
                   << "T"
                   << "ST";
    mInputNameMap.clear();
    mInputNameMap.insert(0, plc::Input_X);
    mInputNameMap.insert(1, plc::Input_SX);
    mInputNameMap.insert(2, plc::Output_Y);
    mInputNameMap.insert(3, plc::Output_SY);
    mInputNameMap.insert(4, plc::Coil_MC);
    mInputNameMap.insert(5, plc::Coil_SMC);
    mInputNameMap.insert(6, plc::Register_UI);
    mInputNameMap.insert(7, plc::Counter_CTU);
    mInputNameMap.insert(8, plc::Timer_T);
    mInputNameMap.insert(9, plc::Timer_ST);

    //输出
    mOutputNameList.clear();
    mOutputNameList << "Y"
                    << "SY"
                    << "MC"
                    << "SMC"
                    << "UI";
    mOuputNameMap.clear();
    mOuputNameMap.insert(0, plc::Output_Y);
    mOuputNameMap.insert(2, plc::Output_SY);
    mOuputNameMap.insert(3, plc::Coil_MC);
    mOuputNameMap.insert(4, plc::Coil_SMC);
    mOuputNameMap.insert(5, plc::Register_UI);

    mParameterType.clear();
    mParameterType << QString::fromLocal8Bit("参数值")
                   << QString::fromLocal8Bit("变量UI")
                   << QString::fromLocal8Bit("变量I");
}

//元件类型变更处理
void CPlcItemEditWidget::setComboboxType(EComponentType type)
{
    //根据不同元件类型，设置下拉菜单项
    blockSignals(true);
    ui->cb_Type->clear();
    ui->cb_Name->clear();
    switch (type)
    {
    case plc::OpenContact:
        ui->cb_Type->addItems(mContactTypeList);
        ui->cb_Type->setCurrentIndex(0);
        ui->cb_Name->clear();
        ui->cb_Name->addItems(mInputNameList);
        mComboboxType = CPlcItemEditWidget::Contact;
        mComboboxName = CPlcItemEditWidget::Input;
        break;
    case plc::CloseContact:
        ui->cb_Type->addItems(mContactTypeList);
        ui->cb_Type->setCurrentIndex(1);
        ui->cb_Name->clear();
        ui->cb_Name->addItems(mInputNameList);
        mComboboxName = CPlcItemEditWidget::Input;
        mComboboxType = CPlcItemEditWidget::Contact;
        break;
    case plc::Pulse:
        ui->cb_Type->addItems(mContactTypeList);
        ui->cb_Type->setCurrentIndex(2);
        ui->cb_Name->clear();
        ui->cb_Name->addItems(mInputNameList);
        mComboboxName = CPlcItemEditWidget::Input;
        mComboboxType = CPlcItemEditWidget::Contact;
        break;
    case plc::Falling:
        ui->cb_Type->addItems(mContactTypeList);
        ui->cb_Type->setCurrentIndex(3);
        ui->cb_Name->clear();
        ui->cb_Name->addItems(mInputNameList);
        mComboboxName = CPlcItemEditWidget::Input;
        mComboboxType = CPlcItemEditWidget::Contact;
        break;
    case plc::Coil:
        ui->cb_Type->addItems(mCoilTypeList);
        ui->cb_Type->setCurrentIndex(0);
        ui->cb_Name->clear();
        ui->cb_Name->addItems(mOutputNameList);
        mComboboxName = CPlcItemEditWidget::Ouput;
        mComboboxType = CPlcItemEditWidget::Coil;
        break;
    case plc::Set:
        ui->cb_Type->addItems(mCoilTypeList);
        ui->cb_Type->setCurrentIndex(1);
        ui->cb_Name->clear();
        ui->cb_Name->addItems(mOutputNameList);
        mComboboxName = CPlcItemEditWidget::Ouput;
        mComboboxType = CPlcItemEditWidget::Coil;
        break;
    case plc::Reset:
        ui->cb_Type->addItems(mCoilTypeList);
        ui->cb_Type->setCurrentIndex(2);
        ui->cb_Name->clear();
        ui->cb_Name->addItems(mOutputNameList);
        mComboboxName = CPlcItemEditWidget::Ouput;
        mComboboxType = CPlcItemEditWidget::Coil;
        break;
    case plc::TON:
        ui->cb_Type->addItems(mFunctionTypeList);
        ui->cb_Type->setCurrentIndex(0);
        ui->cb_Name->clear();
        ui->cb_Name->addItem("T");
        ui->cb_Name->addItem("ST");
        ui->cb_ParameterType->addItems(mParameterType);
        mComboboxName = CPlcItemEditWidget::FunctionName;
        mComboboxType = CPlcItemEditWidget::TON;
        break;
    case plc::TOF:
        ui->cb_Type->addItems(mFunctionTypeList);
        ui->cb_Type->setCurrentIndex(1);
        ui->cb_Name->clear();
        ui->cb_Name->addItem("T");
        ui->cb_Name->addItem("ST");
        ui->cb_ParameterType->addItems(mParameterType);
        mComboboxName = CPlcItemEditWidget::FunctionName;
        mComboboxType = CPlcItemEditWidget::TOF;
        break;
    case plc::TONR:
        ui->cb_Type->addItems(mFunctionTypeList);
        ui->cb_Type->setCurrentIndex(2);
        ui->cb_Name->clear();
        ui->cb_Name->addItem("T");
        ui->cb_Name->addItem("ST");
        ui->cb_ParameterType->addItems(mParameterType);
        mComboboxName = CPlcItemEditWidget::FunctionName;
        mComboboxType = CPlcItemEditWidget::TONR;
        break;
    case plc::CTU:
        ui->cb_Type->addItems(mFunctionTypeList);
        ui->cb_Type->setCurrentIndex(3);
        ui->cb_Name->clear();
        ui->cb_Name->addItem("C");
        ui->cb_ParameterType->addItems(mParameterType);
        mComboboxName = CPlcItemEditWidget::FunctionName;
        mComboboxType = CPlcItemEditWidget::CTU;
        break;
    case plc::RST:
        ui->cb_Type->addItems(mFunctionTypeList);
        ui->cb_Type->setCurrentIndex(4);
        ui->cb_Name->clear();
        ui->cb_Name->addItem("C");
        ui->cb_Name->addItem("T");
        ui->cb_Name->addItem("ST");
        mComboboxName = CPlcItemEditWidget::FunctionName;
        mComboboxType = CPlcItemEditWidget::RST;
        break;
    default:
        break;
    }
    //分类设置参数控件隐藏与否
    switch (mComboboxType)
    {
    case CPlcItemEditWidget::Contact:
    case CPlcItemEditWidget::Coil:
    case CPlcItemEditWidget::RST:
        ui->ll_Parameter->hide();
        ui->sb_Parameter->hide();
        ui->ll_ParameterType->hide();
        ui->cb_ParameterType->hide();
        ui->ll_Bit->hide();
        ui->sb_Bit->hide();
        break;
    default:
        ui->ll_Parameter->show();
        ui->sb_Parameter->show();
        ui->ll_ParameterType->show();
        ui->cb_ParameterType->show();
        ui->ll_Bit->hide();
        ui->sb_Bit->hide();
        break;
    }
    blockSignals(false);
}
//元件名称变更处理
void CPlcItemEditWidget::setComboboxName(EComponentName name)
{
    //根据不同元件类型，设置下拉菜单项
    switch (name)
    {
    case plc::Input_X:
        setCurrentIndexName("X");
        slotChangeComboboxName("X");
        break;
    case plc::Input_SX:
        setCurrentIndexName("SX");
        slotChangeComboboxName("SX");
        break;
    case plc::Output_Y:
        setCurrentIndexName("Y");
        slotChangeComboboxName("Y");
        break;
    case plc::Output_SY:
        setCurrentIndexName("SY");
        slotChangeComboboxName("SY");
        break;
    case plc::Coil_MC:
        setCurrentIndexName("MC");
        slotChangeComboboxName("MC");
        break;
    case plc::Coil_SMC:
        setCurrentIndexName("SMC");
        slotChangeComboboxName("SMC");
        break;
    case plc::Register_UI:
        setCurrentIndexName("UI");
        slotChangeComboboxName("UI");
        break;
    case plc::Counter_CTU:
        setCurrentIndexName("C");
        slotChangeComboboxName("C");
        break;
    case plc::Timer_T:
        setCurrentIndexName("T");
        slotChangeComboboxName("T");
        break;
    case plc::Timer_ST:
        setCurrentIndexName("ST");
        slotChangeComboboxName("ST");
        break;
    }
}

//设置元件名类型
void CPlcItemEditWidget::setCurrentIndexName(QString name)
{
    int32_t index = 0;
    switch (mComboboxType)
    {
    case CPlcItemEditWidget::Contact:
        index = mInputNameList.indexOf(name);
        break;
    case CPlcItemEditWidget::Coil:
        index = mOutputNameList.indexOf(name);
        break;
    case CPlcItemEditWidget::TON:
    case CPlcItemEditWidget::TOF:
    case CPlcItemEditWidget::TONR:
        if (name == "T")
            index = 0;
        else
            index = 1;
        break;
    case CPlcItemEditWidget::CTU:
        index = 0;
        break;
    case CPlcItemEditWidget::RST:
        if (name == "C")
            index = 0;
        else if (name == "T")
            index = 1;
        else
            index = 2;
        break;
    }
    if (index == -1) index = 0;
    ui->cb_Name->setCurrentIndex(index);
}

//变量名变更、对应调整元件编号设置限制
void CPlcItemEditWidget::slotChangeComboboxName(QString str)
{
    if (str == "X")
    {
        ui->sb_Num->setMinimum(0);
        ui->sb_Num->setMaximum(499);
        ui->ll_Bit->hide();
        ui->sb_Bit->hide();
        ui->ll_Num->setText(QString::fromLocal8Bit("元件编号"));
        return;
    }
    else if (str == "SX")
    {
        ui->sb_Num->setMinimum(0);
        ui->sb_Num->setMaximum(319);
        ui->ll_Bit->hide();
        ui->sb_Bit->hide();
        ui->ll_Num->setText(QString::fromLocal8Bit("元件编号"));
        return;
    }
    else if (str == "Y")
    {
        ui->sb_Num->setMinimum(0);
        ui->sb_Num->setMaximum(499);
        ui->ll_Bit->hide();
        ui->sb_Bit->hide();
        ui->ll_Num->setText(QString::fromLocal8Bit("元件编号"));
        return;
    }
    else if (str == "SY")
    {
        ui->sb_Num->setMinimum(0);
        ui->sb_Num->setMaximum(319);
        ui->ll_Bit->hide();
        ui->sb_Bit->hide();
        ui->ll_Num->setText(QString::fromLocal8Bit("元件编号"));
        return;
    }
    else if (str == "MC")
    {
        ui->sb_Num->setMinimum(0);
        ui->sb_Num->setMaximum(4095);
        ui->ll_Bit->hide();
        ui->sb_Bit->hide();
        ui->ll_Num->setText(QString::fromLocal8Bit("元件编号"));
        return;
    }
    else if (str == "SMC")
    {
        ui->sb_Num->setMinimum(0);
        ui->sb_Num->setMaximum(2047);
        ui->ll_Bit->hide();
        ui->sb_Bit->hide();
        ui->ll_Num->setText(QString::fromLocal8Bit("元件编号"));
        return;
    }
    else if (str == "UI")
    {
        ui->sb_Num->setMinimum(0);
        ui->sb_Num->setMaximum(4095);
        ui->ll_Bit->show();
        ui->sb_Bit->show();
        ui->ll_Num->setText(QString::fromLocal8Bit("模块号"));
        ui->ll_Bit->setText(QString::fromLocal8Bit("点位号"));
        return;
    }
    else if (str == "C")
    {
        ui->sb_Num->setMinimum(0);
        ui->sb_Num->setMaximum(19);
    }
    else if (str == "T")
    {
        ui->sb_Num->setMinimum(0);
        ui->sb_Num->setMaximum(79);
    }
    else if (str == "ST")
    {
        ui->sb_Num->setMinimum(0);
        ui->sb_Num->setMaximum(39);
    }

    // 点位号隐藏、设置参数类型
    ui->ll_Bit->hide();
    ui->sb_Bit->hide();
    ui->ll_Num->setText(QString::fromLocal8Bit("元件编号"));
    ui->cb_ParameterType->clear();
    ui->cb_ParameterType->addItems(mParameterType);

    slotChangeComboboxParameterType(mLastItemData.component.parmType);
}

//参数类型变更
void CPlcItemEditWidget::slotChangeComboboxParameterType(int index)
{
	mLastItemData.component.parmType = index;
    //参数类型设置
    switch (mLastItemData.component.parmType)
    {
    case 0:   //无变量
        ui->cb_ParameterType->setCurrentIndex(0);
        ui->ll_Parameter->setText(QString::fromLocal8Bit("参数值"));
        ui->sb_Parameter->setMinimum(0);
        ui->sb_Parameter->setMaximum(9999999);
        break;
    case 1:   // UI变量
        ui->cb_ParameterType->setCurrentIndex(1);
        ui->ll_Parameter->setText(QString::fromLocal8Bit("变量编号"));
        ui->sb_Parameter->setMinimum(0);
        ui->sb_Parameter->setMaximum(9999999);
        break;
    case 2:   // I变量
        ui->cb_ParameterType->setCurrentIndex(2);
        ui->ll_Parameter->setText(QString::fromLocal8Bit("变量编号"));
        ui->sb_Parameter->setMinimum(0);
        ui->sb_Parameter->setMaximum(4095);
        break;
    default:
        break;
    }
}

//类型选择变更
void CPlcItemEditWidget::slotChangeComboboxType(int index)
{
    //触点和线圈不用处理，功能块切换到RST时，界面需要做更新
    if (mComboboxType == CPlcItemEditWidget::Coil ||
        mComboboxType == CPlcItemEditWidget::Contact)
    {
        return;
    }
    else
    {
        blockSignals(true);
        switch (index)
        {
        case 0:   // TON
            ui->cb_Name->clear();
            ui->cb_Name->addItem("T");
            ui->cb_Name->addItem("ST");
            ui->cb_Name->setCurrentIndex(0);
            ui->ll_Parameter->show();
            ui->ll_ParameterType->show();
            ui->cb_ParameterType->show();
            ui->sb_Parameter->show();
            mComboboxType = CPlcItemEditWidget::TON;
            break;
        case 1:
            ui->cb_Name->clear();
            ui->cb_Name->addItem("T");
            ui->cb_Name->addItem("ST");
            ui->cb_Name->setCurrentIndex(0);
            ui->ll_Parameter->show();
            ui->ll_ParameterType->show();
            ui->cb_ParameterType->show();
            ui->sb_Parameter->show();
            mComboboxType = CPlcItemEditWidget::TOF;
            break;
        case 2:
            ui->cb_Name->clear();
            ui->cb_Name->addItem("T");
            ui->cb_Name->addItem("ST");
            ui->cb_Name->setCurrentIndex(0);
            ui->ll_Parameter->show();
            ui->ll_ParameterType->show();
            ui->cb_ParameterType->show();
            ui->sb_Parameter->show();
            mComboboxType = CPlcItemEditWidget::TONR;
            break;
        case 3:
            ui->cb_Name->clear();
            ui->cb_Name->addItem("C");
            ui->cb_Name->setCurrentIndex(0);
            ui->ll_Parameter->show();
            ui->ll_ParameterType->show();
            ui->cb_ParameterType->show();
            ui->sb_Parameter->show();
            mComboboxType = CPlcItemEditWidget::CTU;
            break;
        default:
            QString name = ui->cb_Name->currentText();
            ui->cb_Name->clear();
            ui->cb_Name->addItem("C");
            ui->cb_Name->addItem("T");
            ui->cb_Name->addItem("ST");
            ui->ll_Parameter->hide();
            ui->ll_ParameterType->hide();
            ui->cb_ParameterType->hide();
            ui->sb_Parameter->hide();
            mComboboxType = CPlcItemEditWidget::RST;
            setCurrentIndexName(name);
            break;
        }
        blockSignals(false);
    }
}
